package main

import (
	"errors"
	"fmt"
)

// 定义一个基础错误
var errBase = errors.New("基础错误：操作失败")

// 函数1：模拟一个底层操作，返回基础错误
func operation() error {
	return errBase
}

// 函数2：调用函数1，并添加自定义上下文信息进行错误包装
func operationWithContext() error {
	err := operation()
	if err != nil {
		// 添加自定义上下文信息，这里的上下文信息表明是在特定的业务逻辑中发生的错误
		return fmt.Errorf("在用户注册业务逻辑中：%w", err)
	}
	return nil
}

// 函数3：进一步包装错误并添加更多上下文信息
func higherLevelOperation() error {
	err := operationWithContext()
	if err != nil {
		// 添加更高级别的上下文信息，表明是在处理用户请求时发生的错误
		return fmt.Errorf("处理用户请求时：%w", err)
	}
	return nil
}

func main() {
	err := higherLevelOperation()
	if err != nil {
		fmt.Println("最终错误：", err)

		// 解包错误并检查是否包含基础错误
		if errors.Is(err, errBase) {
			fmt.Println("错误链中包含基础错误")
		}

		// 解包获取上一层的错误
		unwrappedErr := errors.Unwrap(err)
		fmt.Println("上一层错误：", unwrappedErr)

		// 解包获取上一层的错误
		unwrappedErr2 := errors.Unwrap(unwrappedErr)
		fmt.Println("上上一层错误：", unwrappedErr2)

		// 原始错误信息可以通过逐层解包获取
		originalErr := errors.Unwrap(unwrappedErr2)
		if originalErr != nil {
			fmt.Println("原始错误：", originalErr)
		} else {
			fmt.Println("unwrappedErr2 已经是原始错误")
		}
	}
}
